package com.sansan.qiangji.realize.warehouse;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sansan.qiangji.VO.warehouse.pushOrder.PushOrderBoxDetailVO;
import com.sansan.qiangji.VO.warehouse.pushOrder.PushOrderDetailVO;
import com.sansan.qiangji.VO.warehouse.pushOrder.PushOrderListResultVO;
import com.sansan.qiangji.VO.warehouse.pushOrder.PushOrderVO;
import com.sansan.qiangji.dto.PushOrderDetailExcelDto;
import com.sansan.qiangji.dto.PushOrderExcelDto;
import com.sansan.qiangji.entity.base.Product;
import com.sansan.qiangji.entity.warehouse.PushOrder;
import com.sansan.qiangji.entity.warehouse.PushOrderBoxDetail;
import com.sansan.qiangji.entity.warehouse.PushOrderDetail;
import com.sansan.qiangji.entity.warehouse.example.PushOrderBoxDetailExample;
import com.sansan.qiangji.entity.warehouse.example.PushOrderDetailExample;
import com.sansan.qiangji.entity.warehouse.example.PushOrderExample;
import com.sansan.qiangji.enums.ResultEnum;
import com.sansan.qiangji.exception.ServiceException;
import com.sansan.qiangji.form.warehouse.PushOrderAddForm;
import com.sansan.qiangji.form.warehouse.PushOrderEditForm;
import com.sansan.qiangji.form.warehouse.PushOrderListForm;
import com.sansan.qiangji.service.impl.base.ProductServiceImpl;
import com.sansan.qiangji.service.inter.warehouse.PushOrderBoxDetailService;
import com.sansan.qiangji.service.inter.warehouse.PushOrderDetailService;
import com.sansan.qiangji.service.inter.warehouse.PushOrderService;
import com.sansan.qiangji.utils.DateUtil;
import com.sansan.qiangji.utils.StringUtil;
import com.sansan.qiangji.utils.pageUtils.PageResult;
import com.sansan.qiangji.utils.pageUtils.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PushOrderReal {
    @Autowired
    private PushOrderService pushOrderService;

    @Autowired
    private PushOrderDetailService pushOrderDetailService;

    @Autowired
    private PushOrderBoxDetailService pushOrderBoxDetailService;

    @Autowired
    private ProductServiceImpl productService;

    @Transactional
    public void deletePushOrder(Integer pushOrderId){
        PushOrder pushOrder = pushOrderService.selectByPrimaryKey(pushOrderId);
        if(pushOrder==null){
            log.error("【入库单删除】入库单不存在，pushOrderId={}",pushOrderId);
            throw new ServiceException(ResultEnum.PUSH_ORDER_IS_NOT_EXIST);
        }
        int row = pushOrderService.deleteByPrimaryKey(pushOrderId);
        if(row==0){
            log.error("【入库单删除】入库单删除失败，pushOrderId={}",pushOrderId);
            throw new ServiceException(ResultEnum.PUSH_ORDER_DELETE_ERROR);
        }
    }

    @Transactional
    public void addPushOrder(PushOrderAddForm pushOrderAddForm){
        PushOrderExample pushOrderExample = new PushOrderExample();
        pushOrderExample.or().andBatchNumberEqualTo(pushOrderAddForm.getBatchNumber());
        List<PushOrder> pushOrders = pushOrderService.selectByExample(pushOrderExample);
        if (pushOrders.size() != 0){
            log.error("【入库单导入】入库单批次已存在");
            throw new ServiceException(ResultEnum.PUSH_ORDER_BATCH_NUMBER_EXIST);
        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        //自动生成入库单号
        String code = StringUtil.codeGenerater("push");
        PushOrder pushOrder = new PushOrder();
        BeanUtils.copyProperties(pushOrderAddForm,pushOrder);
        pushOrder.setPushOrderCode(code);
        pushOrder.setPushOrderStatus("未入库");
        pushOrder.setPushOrderOwn(request.getAttribute("userName").toString());
        pushOrder.setPullOrderCode("无");
        int row = pushOrderService.insert(pushOrder);
        if(row==0){
            log.error("【入库单新增】入库单新增失败");
            throw new ServiceException(ResultEnum.PUSH_ORDER_INSERT_ERROR);
        }
    }


    @Transactional
    public void editPushOrder(PushOrderEditForm pushOrderEditForm){
        PushOrder pushOrder = new PushOrder();
        PushOrder order = pushOrderService.selectByPrimaryKey(pushOrderEditForm.getPushOrderId());
        BeanUtils.copyProperties(pushOrderEditForm,pushOrder);
        pushOrder.setPushOrderCode(order.getPushOrderCode());
        int row = pushOrderService.updateByPrimaryKey(pushOrder);
        if(row==0){
            log.error("【入库单新增】入库单新增失败");
            throw new ServiceException(ResultEnum.PUSH_ORDER_INSERT_ERROR);
        }
    }

    public PushOrderListResultVO pushOrderList(PushOrderListForm pushOrderListForm){
        PushOrderExample example = new PushOrderExample();
        PushOrderExample.Criteria criteria = example.createCriteria();
        if (pushOrderListForm.getPushOrderCode() != null){
            criteria.andPushOrderCodeLike("%"+pushOrderListForm.getPushOrderCode()+"%");
        }
        if(pushOrderListForm.getBatchNumber()!=null&&!"".equals(pushOrderListForm.getBatchNumber())){
            criteria.andBatchNumberLike("%" + pushOrderListForm.getBatchNumber() + "%");
        }
        if(pushOrderListForm.getPushOrderStatus()!=null&&!"".equals(pushOrderListForm.getPushOrderStatus())){
            criteria.andPushOrderStatusLike(pushOrderListForm.getPushOrderStatus() );
        }
        if(pushOrderListForm.getPushOrderOwn()!=null&&!"".equals(pushOrderListForm.getPushOrderOwn())){
            criteria.andPushOrderOwnLike("%"+ pushOrderListForm.getPushOrderOwn()+"%" );
        }
        if(pushOrderListForm.getQueryTime()!=null&&pushOrderListForm.getQueryTime().size()!=0){
            String startTime = pushOrderListForm.getQueryTime().get(0)+" 00:00:00";
            String endTime = pushOrderListForm.getQueryTime().get(1)+" 23:59:59";
            Date start = DateUtil.string2Date(startTime,"yyyy-MM-dd HH:mm:ss");
            Date end = DateUtil.string2Date(endTime,"yyyy-MM-dd HH:mm:ss");
            criteria.andPushOrderCreatimeBetween(start,end);
        }
        example.setOrderByClause("push_order_creatime desc");
        int pageNum = pushOrderListForm.getPageNum();
        int pageSize = pushOrderListForm.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        List<PushOrder> pushOrderList = pushOrderService.selectByExample(example);
        PageResult<PushOrder> pushOrderPageResult = PageUtil.getPageResult(new PageInfo<>(pushOrderList));
        PushOrderListResultVO pushOrderListResultVO = new PushOrderListResultVO();
        BeanUtils.copyProperties(pushOrderPageResult,pushOrderListResultVO);
        List<PushOrderVO> pushOrderVOS = new ArrayList<>();

        for(PushOrder pushOrder : pushOrderPageResult.getContent()){
            PushOrderVO pushOrderVO = new PushOrderVO();
            BeanUtils.copyProperties(pushOrder,pushOrderVO);
            //查找入库单详情
            PushOrderDetailExample pushOrderDetailExample = new PushOrderDetailExample();
            pushOrderDetailExample.or().andPushOrderCodeEqualTo(pushOrder.getPushOrderCode());
            List<PushOrderDetail> pushOrderDetails = pushOrderDetailService.selectByExample(pushOrderDetailExample);
            List<PushOrderDetailVO> pushOrderDetailVOS = new ArrayList<>();
            for(PushOrderDetail pushOrderDetail : pushOrderDetails){
                PushOrderDetailVO pushOrderDetailVO = new PushOrderDetailVO();
                BeanUtils.copyProperties(pushOrderDetail,pushOrderDetailVO);
                //查找箱子详情
                PushOrderBoxDetailExample pushOrderBoxDetailExample = new PushOrderBoxDetailExample();
                pushOrderBoxDetailExample.or().andPushOrderDetailCodeEqualTo(pushOrderDetail.getPushOrderDetailCode());
                List<PushOrderBoxDetail> boxDetails = pushOrderBoxDetailService.selectByExample(pushOrderBoxDetailExample);
                List<PushOrderBoxDetailVO> boxDetailVOS = new ArrayList<>();
                for(PushOrderBoxDetail boxDetail : boxDetails){
                    PushOrderBoxDetailVO pushOrderBoxDetailVO = new PushOrderBoxDetailVO();
                    BeanUtils.copyProperties(boxDetail,pushOrderBoxDetailVO);
                    boxDetailVOS.add(pushOrderBoxDetailVO);
                }
                pushOrderDetailVO.setPushOrderBoxDetailVOS(boxDetailVOS);
                pushOrderDetailVOS.add(pushOrderDetailVO);
            }

            pushOrderVO.setPushOrderDetailVOS(pushOrderDetailVOS);
            pushOrderVOS.add(pushOrderVO);
        }
        pushOrderListResultVO.setPushOrderVOS(pushOrderVOS);
        return pushOrderListResultVO;
    }

    public List<PushOrderDetailExcelDto> getAllPushOrderDto(String pushOrderCode){
        PushOrderDetailExample pushOrderDetailExample = new PushOrderDetailExample();
        pushOrderDetailExample.or().andPushOrderCodeEqualTo(pushOrderCode);
        List<PushOrderDetail> pushOrderDetails = pushOrderDetailService.selectByExample(pushOrderDetailExample);
        List<PushOrderDetailExcelDto> pushOrderExcelDtos = new ArrayList<>();
        for (PushOrderDetail pushOrderDetail : pushOrderDetails){
            PushOrderDetailExcelDto pushOrderExcelDto = new PushOrderDetailExcelDto();
            BeanUtils.copyProperties(pushOrderDetail, pushOrderExcelDto);
            pushOrderExcelDtos.add(pushOrderExcelDto);
        }
        return pushOrderExcelDtos;
    }

    public List<PushOrderDetailExcelDto> getAllPushOrderDtoByDate(Date startTime, Date endTime){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endTime);
        calendar.add(Calendar.DATE, 1);
        endTime = calendar.getTime();
        PushOrderDetailExample pushOrderDetailExample = new PushOrderDetailExample();
        pushOrderDetailExample.or().andCreateTimeBetween(startTime, endTime);
        List<PushOrderDetail> pushOrderDetails = pushOrderDetailService.selectByExample(pushOrderDetailExample);
        List<PushOrderDetailExcelDto> pushOrderExcelDtos = new ArrayList<>();
        for (PushOrderDetail pushOrderDetail : pushOrderDetails){
            PushOrderDetailExcelDto pushOrderExcelDto = new PushOrderDetailExcelDto();
            BeanUtils.copyProperties(pushOrderDetail, pushOrderExcelDto);
            pushOrderExcelDtos.add(pushOrderExcelDto);
        }
        return pushOrderExcelDtos;
    }

    @Transactional
    public void uploadPushOrderExcel(List<PushOrderExcelDto> pushOrderExcelDtos){
        List<Product> products = new ArrayList<>();
        PushOrderExample pushOrderExample = new PushOrderExample();
        pushOrderExample.or().andBatchNumberEqualTo(pushOrderExcelDtos.get(0).getBatchNumber());
        List<PushOrder> pushOrders = pushOrderService.selectByExample(pushOrderExample);
        if (pushOrders.size() != 0){
            log.error("【入库单导入】入库单批次已存在");
            throw new ServiceException(ResultEnum.PUSH_ORDER_BATCH_NUMBER_EXIST);
        }
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        for (PushOrderExcelDto pushOrderExcelDto : pushOrderExcelDtos){
            Product product = new Product();
            BeanUtils.copyProperties(pushOrderExcelDto, product);
            products.add(product);
        }
        // 自动添加物料基础信息
        List<Product> productList = productService.selectProducts(products);
        for (Product product : productList){
            List<Product> products1 = products.stream().filter(e->e.getProductName().equals(product.getProductName())||e.getProductCode().equals(product.getProductCode())).collect(Collectors.toList());
            if (products1.size()!=0){
                if (!product.getProductCode().equals(products1.get(0).getProductCode())||!product.getProductName().equals(products1.get(0).getProductName())){
                    List<PushOrderExcelDto> pushOrderExcelDtoList = pushOrderExcelDtos.stream().filter(e->e.getProductCode().equals(products1.get(0).getProductCode())).collect(Collectors.toList());
                    int rowIndex = -1;
                    if (pushOrderExcelDtoList.size()!=0){
                        if (pushOrderExcelDtoList.get(0).getPushOrderIndex() != null){
                            rowIndex = pushOrderExcelDtoList.get(0).getPushOrderIndex();
                        }
                    }
                    log.error("【入库单导入】物料编号、物料名称与物料基础信息不匹配");
                    throw new ServiceException(ResultEnum.PRODUCT_IS_NOT_SAME_WITH_BASE.getCode(), "第 "+ rowIndex +" 行 物料编号、物料名称与物料基础信息不匹配！");
                }
                products.remove(products1.get(0));
            }
        }
        if (products.size()!=0){
            productService.insertProducts(products);
        }
        // 生成入库单
        PushOrder pushOrder = new PushOrder();
        String pushOrderCode = StringUtil.codeGenerater("push");
        pushOrder.setPushOrderCode(pushOrderCode);
        pushOrder.setBatchNumber(pushOrderExcelDtos.get(0).getBatchNumber());
        pushOrder.setPushOrderStatus("未入库");
        pushOrder.setPushOrderCreatime(new Date());
        pushOrder.setPushOrderOwn(request.getAttribute("userName").toString());
        pushOrder.setPullOrderCode("无");
        pushOrderService.insert(pushOrder);
        // 生成入库详情单
        List<PushOrderDetail> pushOrderDetails = new ArrayList<>();
        String pushOrderDetailCode = StringUtil.codeGenerater("push_detail");
        int i = 0;
        for (PushOrderExcelDto pushOrderExcelDto : pushOrderExcelDtos){
            PushOrderDetail pushOrderDetail = new PushOrderDetail();
            BeanUtils.copyProperties(pushOrderExcelDto, pushOrderDetail);
            pushOrderDetail.setPushOrderCode(pushOrderCode);
            pushOrderDetail.setPushOrderDetailCode(pushOrderDetailCode + String.format("%03d", i));
            pushOrderDetail.setProductPushPace("进行中");
            pushOrderDetail.setPushOrderCount(Integer.parseInt(pushOrderExcelDto.getUnintCount()));
            pushOrderDetail.setBatchNumber(pushOrderExcelDtos.get(0).getBatchNumber());
            List<Product> products1 = productList.stream().filter(e->e.getProductCode().equals(pushOrderExcelDto.getProductCode())).collect(Collectors.toList());
            pushOrderDetail.setCountBox(0);
            if (products1.size() !=0){
                pushOrderDetail.setCountBox(products1.get(0).getCountBox());
            }
            pushOrderDetail.setCreateTime(new Date());
            pushOrderDetails.add(pushOrderDetail);
            i++;
        }
        pushOrderDetailService.insertPushOrderDetails(pushOrderDetails);
    }
}
